using Fusion.Frameworks.Notification;
using Fusion.Frameworks.UI;
using Fusion.Hotfix.Adapters;
using Fusion.Hotfix.ValueTypeBinders;
using Fusion.Net;
using Google.Protobuf;
using ILRuntime.Runtime.Enviorment;
using ILRuntime.Runtime.Intepreter;
using UnityEngine;
using UnityEngine.EventSystems;

namespace Fusion.Hotfix
{
    public class DLLBinder
    {
        protected AppDomain appDomain;
        public DLLBinder(AppDomain appDomain)
        {
            this.appDomain = appDomain;
        }

        public virtual void RegisterAdapters()
        {
            appDomain.RegisterCrossBindingAdaptor(new UIObjectAdapter());
            appDomain.RegisterCrossBindingAdaptor(new UIDataAdapter());
            appDomain.RegisterCrossBindingAdaptor(new DLLMonoBaseAdapter());
            appDomain.RegisterCrossBindingAdaptor(new CoroutineAdapter());
            appDomain.RegisterCrossBindingAdaptor(new DLLMonoDataAdapter());
            appDomain.RegisterCrossBindingAdaptor(new IMessageAdapter());
            appDomain.RegisterCrossBindingAdaptor(new INotificationDataAdapter());
        }

        public virtual void RegisterValueTypeBinders()
        {
            appDomain.RegisterValueTypeBinder(typeof(Vector3), new Vector3Binder());
            appDomain.RegisterValueTypeBinder(typeof(Vector2), new Vector2Binder());
            appDomain.RegisterValueTypeBinder(typeof(Quaternion), new QuaternionBinder());
        }

        public virtual void RegisterMethodDelegate()
        {
            appDomain.DelegateManager.RegisterMethodDelegate<GameObject>();
            appDomain.DelegateManager.RegisterMethodDelegate<int>();
            appDomain.DelegateManager.RegisterMethodDelegate<float>();
            appDomain.DelegateManager.RegisterMethodDelegate<double>();
            appDomain.DelegateManager.RegisterMethodDelegate<byte>();
            appDomain.DelegateManager.RegisterMethodDelegate<char>();
            appDomain.DelegateManager.RegisterMethodDelegate<string>();
            appDomain.DelegateManager.RegisterMethodDelegate<bool>(); 
            appDomain.DelegateManager.RegisterMethodDelegate<INotificationData>(); 
            appDomain.DelegateManager.RegisterMethodDelegate<ILTypeInstance>();

            appDomain.DelegateManager.RegisterMethodDelegate<GameObject, int, int>();
            appDomain.DelegateManager.RegisterMethodDelegate<PointerEventData>();
            appDomain.DelegateManager.RegisterMethodDelegate<SocketBase, byte[]>();
            appDomain.DelegateManager.RegisterMethodDelegate<SocketBase>();
            appDomain.DelegateManager.RegisterMethodDelegate<SocketBase, ExceptionData>();
            appDomain.DelegateManager.RegisterMethodDelegate<SocketBase, int>();
        }

        public virtual void RegisterFunctionDelegate()
        {
            appDomain.DelegateManager.RegisterFunctionDelegate<GameObject>();
            appDomain.DelegateManager.RegisterFunctionDelegate<int>();
            appDomain.DelegateManager.RegisterFunctionDelegate<float>();
            appDomain.DelegateManager.RegisterFunctionDelegate<double>();
            appDomain.DelegateManager.RegisterFunctionDelegate<byte>();
            appDomain.DelegateManager.RegisterFunctionDelegate<char>();
            appDomain.DelegateManager.RegisterFunctionDelegate<string>();
            appDomain.DelegateManager.RegisterFunctionDelegate<bool>();
            appDomain.DelegateManager.RegisterFunctionDelegate<ILTypeInstance>();
            appDomain.DelegateManager.RegisterFunctionDelegate<UIObject, bool>();
            appDomain.DelegateManager.RegisterFunctionDelegate<IMessageAdapter.Adapter, ILTypeInstance>();
            appDomain.DelegateManager.RegisterFunctionDelegate<IMessage>();
        }

        public virtual void RegisterDelegateConvertor()
        {
        }

        public virtual void RegisterCLRBinding()
        {
        }

        public void Register()
        {
            RegisterAdapters();
            RegisterValueTypeBinders();
            RegisterMethodDelegate();
            RegisterFunctionDelegate();
            RegisterDelegateConvertor();
            RegisterCLRBinding();
        }
    }
}

